package other.xsy.passlys.contract;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.rkhd.platform.sdk.data.model.Contract;
import com.rkhd.platform.sdk.data.model.Opportunity;
import com.rkhd.platform.sdk.data.model.Order;
import com.rkhd.platform.sdk.data.model.OrderProduct;
import com.rkhd.platform.sdk.log.Logger;
import com.rkhd.platform.sdk.log.LoggerFactory;
import com.rkhd.platform.sdk.model.OperateResult;
import com.rkhd.platform.sdk.model.XObject;
import com.rkhd.platform.sdk.service.XObjectService;
import com.rkhd.platform.sdk.trigger.DataResult;
import com.rkhd.platform.sdk.trigger.Trigger;
import com.rkhd.platform.sdk.trigger.TriggerRequest;
import com.rkhd.platform.sdk.trigger.TriggerResponse;
import org.apache.commons.lang.StringUtils;
import other.xsy.passlys.util.HCXObjectService;
import other.xsy.passlys.util.HcUtils;
import other.xsy.passlys.util.PromotionApiUtil;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 功能描述：合同创建后进行处理，计算合同编码
 *
 * @author hzh
 * @ClassName: ContractNoTrigger
 * @Description:
 * @date 2024年03月28日
 */
public class ContractAddDeal implements Trigger {
    private static HCXObjectService hcxObjectService = new HCXObjectService();
    private static final Logger logger = LoggerFactory.getLogger();
    private static String LOGGER_MSG = "合同创建后进行处理 ==> ";

    /**
     * Trigger 事件处理
     * @param request
     * @return
     */
    @Override
    public TriggerResponse execute(TriggerRequest request) {
        List<XObject> dataList = request.getDataList();
        List<DataResult> dataResultList = new ArrayList<>();
        List<Contract> contracts = new ArrayList<>();
        for (XObject xObject : dataList) {
            Contract contract = (Contract) xObject;
            contracts.add(contract);
            dataResultList.add(new DataResult(true, "", contract));
        }
        contractAddAfter(contracts.get(0));
        return new TriggerResponse(true, "", dataResultList);
    }

    public static void main(String[] args) throws Exception {
        HCXObjectService.isLocal = true;
        ContractAddDeal contractAddDeal = new ContractAddDeal();

        Contract contract = new Contract();
        contract.setId(3737672782731914L);
        contract = hcxObjectService.get(contract);
        contractAddDeal.contractAddAfter(contract);

        //contractAddDeal.createOrderByContract(contract);
    }

    public void contractAddAfter(Contract contract) {
        // 处理合同编码
        dealContractCode(contract);

        // 生成订单明细
        createOrderByContract(contract);
    }

    /**
     * 根据合同生成订单 （没有报价单就取预算、概算生成订单；）
     * @param contract
     * @return
     */
    public void createOrderByContract(Contract contract) {
        try {
            logger.info(LOGGER_MSG + "开始处理创建订单");
            Long contractId = contract.getId();
            Long entityType = contract.getEntityType(); //  项目合同: 3343981728602779 预交付合同: 3344120169699944
            Long quote = contract.getOffer__c(); // 报价单
            Long opportunityId = contract.getOpportunityId(); // 业务机会

            // 只判断业务类型为 项目订单: 3309750193298054 预交付订单: 3309752318565039
            List<Long> dealTypeList = Arrays.asList(3343981728602779L, 3344120169699944L);
            if (!dealTypeList.contains(entityType)) {
                logger.info(LOGGER_MSG + "当前合同业务类型无需处理");
                return;
            }

            // 是否有选报价单，有则无需处理
            if (quote != null) {
                logger.info(LOGGER_MSG + "当前合同有选择报价单，无需处理");
                return;
            }

            // 根据业务机会获取PMS概算或者预算数据
            Opportunity opportunity = new Opportunity();
            opportunity.setId(opportunityId);
            opportunity = hcxObjectService.get(opportunity);
            JSONObject pmsOrderDetail = PromotionApiUtil.getPmsOrderDetail(opportunity);
            if (pmsOrderDetail == null || pmsOrderDetail.getString("preEstimateList") == null) {
                logger.error(LOGGER_MSG + "查询PMS预算、概算数据异常");
                return;
            }

            // 根据概算、预算生成订单明细
            List<JSONObject> preEstimateList = JSONArray.parseArray(pmsOrderDetail.getString("preEstimateList"), JSONObject.class);
            logger.info(LOGGER_MSG + "preEstimateList = " + preEstimateList.size());
            if (preEstimateList.size() <= 0) {
                logger.error(LOGGER_MSG + "PMS数据为空");
                return;
            }

            // 根据产品编码获取到CRM产品数据
            String productMaterialNos = preEstimateList.stream().map(v -> "'" + v.getString("productMaterialNo") + "'").distinct().collect(Collectors.joining(","));
            String sql = String.format("select id,productCode__c,productName,fscProductSpec,ProductDescription__c " +
                    "from product where productStatus__c = 1 and productCode__c in (%s)", productMaterialNos);
            List<JSONObject> crmProductList = hcxObjectService.batchXoqlQuery(sql);

            // 获取税率通用选项集
            JSONArray taxRatePicks = HcUtils.getGlobalPicks("globalPick83__c");

            // 项目订单：3309750193298054  预交付订单：3309752318565039
            Order order = new Order();
            order.setEntityType(entityType == 3344120169699944L ? 3309752318565039L : 3309750193298054L);
            order.setContractId(contractId); // 关联合同
            order.setAccountId(contract.getAccountId()); // 最终客户
            order.setTransactionDate(System.currentTimeMillis()); // 下单时间
            order.setOrderSigningDate__c(contract.getSignDate()); // 订单签署日
            order.setFinalCustomerName__c(contract.getClientName__c()); // 签约客户
            order.setOurCompanyName__c(contract.getOurCompanyName__c()); // 我司公司名称
            order.setOpportunityId(contract.getOpportunityId()); // 业务机会
            order.setCustomItem210__c("1"); // 自动序号
            order.setContact__c(contract.getContactPerson__c()); // 联系人
            order.setTelephone1__c(contract.getTelephone__c()); // 联系人电话
            order.setAddress2__c(contract.getAddress__c()); // 联系人通讯地址
            order.setAddress2__c(contract.getMail__c()); // 联系人电子邮件
            order.setOrderName__c(contract.getTitle()); // 订单名
            order.setResponsibleSelling__c(contract.getResponsibleSelling__c()); // 责任销售
            order.setDeliveryManager__c(contract.getDeliveryManager__c()); // 交付负责人
            order.setProjectDeliveryType__c(opportunity.getProjectDeliveryType__c()); // 项目交付类型
            order.setPreSales__c(opportunity.getPreSales__c()); // 行业售前
            order.setBUcounterpart__c(opportunity.getBUcounterpart__c__c()); // 产品/解决方案销售
            order.setSolutionBeforeSale__c(opportunity.getSolutionBeforeSale__c()); // 产品/解决方案售前
            order.setRelevance__c(opportunity.getProjectType__c()); // 项目所属类型

            // 订单总金额
            double amount = preEstimateList.stream().map(v -> new BigDecimal(v.getString("totalPriceTax"))).collect(Collectors.reducing(BigDecimal.ZERO, BigDecimal::add)).doubleValue();
            order.setAmount(amount);

            OperateResult insert = hcxObjectService.insert(order);
            Long orderId = insert.getDataId();
            logger.error(LOGGER_MSG + "orderId = " + orderId);

            // 处理订单明细
            List<OrderProduct> crmAddList = new ArrayList<>();
            for (JSONObject preEstimate : preEstimateList) {
                OrderProduct orderProduct = new OrderProduct();
                orderProduct.setEntityType(3344183093435028L);
                orderProduct.setOrderId(orderId); // 订单
                orderProduct.setQuantity(1.0); // 数量
                orderProduct.setQuantity2__c(1.0); // 数量
                orderProduct.setUnitPrice(preEstimate.getDouble("totalPriceTax")); // 单价
                orderProduct.setPriceTotal(preEstimate.getDouble("totalPriceTax")); // 合同金额
                orderProduct.setCustomItem193__c(contractId); // 合同

                // 产品
                String productMaterialNo = preEstimate.getString("productMaterialNo");
                JSONObject product = crmProductList.stream().filter(v -> Objects.equals(v.getString("productCode__c"), productMaterialNo)).findFirst().orElse(null);
                if (product != null) {
                    orderProduct.setProductId(product.getLong("id")); // 产品
                    orderProduct.setProductNameB__c(product.getString("productName")); // 产品名称
                    orderProduct.setSpecificationModel__c(product.getString("fscProductSpec")); // 规格型号
                    orderProduct.setLineRemarks__c(product.getString("ProductDescription__c")); // 产品描述
                }

                // 税率处理
                String taxRate = preEstimate.getString("taxRate");
                if (StringUtils.isNotBlank(taxRate)) {
                    taxRate = taxRate.replace("%", "");
                    orderProduct.setSF_SL__c(HcUtils.getGeneralValue(taxRatePicks, taxRate)); // 税率
                    orderProduct.setTaxRate__c(Double.valueOf(taxRate) / 100); // 税率（赋值）
                }
                crmAddList.add(orderProduct);
            }
            logger.error(LOGGER_MSG + "crmAddList = " + crmAddList.size());
            hcxObjectService.batchInsert(crmAddList);

            // 更新合同的一号订单
            Contract upContract = new Contract();
            upContract.setId(contractId);
            upContract.setOrder1__c(orderId);
            hcxObjectService.update(upContract);

            logger.info(LOGGER_MSG + "创建订单完成");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("系统异常!!!" + e.getMessage());
        }
    }


    /**
     * 处理合同编码
     * @param contract
     */
    public void dealContractCode(Contract contract) {
        try {
            logger.info(LOGGER_MSG + "开始处理合同编码:" + contract);
            String sf_id__c = contract.getSF_ID__c();
            if(sf_id__c != null){
                return;
            }

            // 获取编码
            Long contractId = contract.getId();
            Long entityType = contract.getEntityType();
            Long ourCompanyId = contract.getOurCompanyName__c(); // 我司公司名称
            String code = createContractCode(entityType, contractId, ourCompanyId);
            if (StringUtils.isBlank(code)) {
                logger.error("生成编号为空!!!");
                return;
            }

            String contractCode = contract.getContractCode();
            if (code.equals(contractCode)) {
                logger.info("生成后的编号和原来的编号一致。无需继续执行！");
                return;
            }

            // 修改合同编码
            Contract upContract = new Contract();
            upContract.setId(contractId);
            upContract.setContractCode(code);
            hcxObjectService.update(upContract);

            // 重新修改订单的编码
            updateOrderNo(contractId, code);
            logger.info(LOGGER_MSG + "开始处理合同编码结束");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("系统异常!!!" + e.getMessage());
        }
    }

    /**
     * 获取合同编码
     * @param entityType
     * @param contractId
     * @return
     * @throws Exception
     */
    private String createContractCode(Long entityType, Long contractId, Long ourCompanyId) throws Exception {
        String resultCode = "";

        // 需要处理的合同类型
        List<Long> dealEntityType = new ArrayList<Long>(){{
            add(11010001500001L); // 业务类型：标准-会议服务合同
            add(3204054904180001L); // 业务类型：标准-天客云方案
            add(3343981728602779L); // 业务类型：项目合同
            add(3344120169699944L); // 业务类型：预交付合同
        }};
        Long ktCompanyId = 3204116332645651L;  // 广州科天视畅信息科技有限公司id


        String prefix = ""; // 前缀标识
        Date date = new Date();
        String year = String.format("%tC%ty", date, date); // 年份 2024
        logger.info(LOGGER_MSG + "year: " + year);

        String sql = "";
        String entityTypes = StringUtils.join(dealEntityType, ",");
        // 获取合同的前缀标识、sql
        if (dealEntityType.contains(entityType)) {
            logger.info(LOGGER_MSG + "需要处理的合同类型");
            // 需要处理的合同类型
            sql = "select id,contractCode,entityType,ourCompanyName__c from contract where SF_ID__c is null and entityType in (" + entityTypes + ") ";
            // 签约主体是否是广州科天
            if (ourCompanyId.equals(ktCompanyId)) {
                prefix = "KTSC";
                sql += " and ourCompanyName__c = " + ktCompanyId;
            } else {
                prefix = "GCES";
                sql += " and ourCompanyName__c != " + ktCompanyId;
            }
            // 不能使用创建日期倒序取最新的合同编号，因为有的会后期进行变更主体修改合同编号 （排除用户 流星 的数据：会有导入的历史数据）
            //sql += " and contractCode is not null order by createdAt desc";
            sql += " and contractCode is not null and id != " + contractId + " and createdBy != 3225345737248087 order by contractCode desc";
        } else {
            logger.info(LOGGER_MSG + "其它合同类型");
            prefix = "GeTsz-EO";
            year = String.format("%ty%tm", date, date); // 特殊处理: 年的后两位 + 月份 （2408） （排除用户 流星 的数据：会有导入的历史数据）
            sql = "select id,contractCode,entityType,ourCompanyName__c from contract where SF_ID__c is null and entityType not in (" + entityTypes + ") " +
                    " and contractCode is not null and id != " + contractId + " and createdBy != 3225345737248087 order by contractCode desc";
        }

        // 获取最新的一条合同编号 如果为空则序号为1直接返回
        logger.info(LOGGER_MSG + "sql = " + sql);
        Contract contract = hcxObjectService.queryOne(sql, Contract.class);
        logger.info("最新的合同数据：" + contract);
        if (contract == null) {
            logger.info(LOGGER_MSG + "没有查到合同信息，返回初始化编码");
            resultCode = prefix + "-" + year + "-" + String.format("%04d", 1);
            return resultCode;
        }

        // 获取最新的合同编码，以及年月、序号
        String contractCode = contract.getContractCode();
        logger.info(LOGGER_MSG + "最新的合同编码：" + contractCode);
        String[] codeSplit = contractCode.split("-");
        if (codeSplit.length < 3) {
            logger.error(LOGGER_MSG + "当前合同编码异常");
        }

        // 编码进行判断
        String codeNo = codeSplit[codeSplit.length - 1]; // 合同编码月
        String codeYear = codeSplit[codeSplit.length - 2]; // 合同编码序号
        if (!year.equals(codeYear)) {
            logger.info(LOGGER_MSG + "不是本年/月数据，返回初始化编码" + codeYear);
            resultCode = prefix + "-" + year + "-" + String.format("%04d", 1);
        } else {
            // 给编码的序号 + 1
            resultCode = prefix + "-" + year + "-" + String.format("%04d", Integer.parseInt(codeNo) + 1);
        }
        logger.info(LOGGER_MSG + "resultCode: " + resultCode);
        return resultCode;
    }

    /**
     * 更新合同订单下的序号
     * @param id
     * @param no
     * @throws Exception
     */
    private void updateOrderNo(Long id, String no) throws Exception {
        String sql = "select id,po from _order where contractId = " + id + " order by createdAt ASC";
        List<Order> orderList = hcxObjectService.queryAll(sql, Order.class);
        logger.info("合同下的订单数量：" + orderList.size());
        if (orderList.size() <= 0) {
            return;
        }

        for (int i = 0; i < orderList.size(); i++) {
            String newNO = no + "-" + String.format("%02d", (i + 1));
            Order order = orderList.get(i);
            order.setPo(newNO);
        }
        Boolean update = hcxObjectService.batchUpdate(orderList);
        logger.info("批量修改合同下的订单编号：" + update);
    }


}
